import { getToken, getWebSocketUrl } from '@/util/storage'
import { checkLogin } from '@/api/auth/authUserApi'
import { isFunction } from '@/util/validate'

function doNewWebSocket() {
  if (ws) {
    return
  }
  console.log('doNewWebSocket()')
  checkLogin({})
  try {
    ws = new WebSocket(getWebSocketUrl() + '?accessToken=' + getToken())
    ws.onopen = (e) => {
      console.log('ws connect success')
      isConnect = true
      eList.forEach(item => {
        if (item) {
          if (isFunction(item.onopen)) {
            item.onopen(e)
          }
          if (item.room) {
            bindRoom(item.room)
          }
        }
      })
    }
    ws.onerror = (e) => {
      console.error(e)
      eList.forEach(item => {
        if (item && isFunction(item.onerror)) {
          item.onerror(e)
        }
      })
      ws.close()
      ws = null
      isConnect = false
    }
    ws.onclose = (e) => {
      console.error(e)
      eList.forEach(item => {
        if (item && isFunction(item.onclose)) {
          item.onclose(e)
        }
      })
      ws = null
      isConnect = false
      setTimeout(() => {
        doNewWebSocket()
      }, 120 * 1000)
    }
    ws.onmessage = (e) => {
      const data = JSON.parse(e.data)
      eList.forEach(item => {
        if (item && item.room === data.room && isFunction(item.onmessage)) {
          item.onmessage(data)
        }
      })
    }
  } catch (e) {
    setTimeout(() => {
      doNewWebSocket()
    }, 120 * 1000)
  }
}

let ws = null
let isConnect = false
const eList = []

export function listenWebSocket(param) {
  if (!ws) {
    doNewWebSocket()
  }
  let haveRoom = false
  eList.forEach(item => {
    if (item && item.room === param.room) {
      haveRoom = true
    }
  })
  eList.push(param)
  if (!haveRoom) {
    bindRoom(param.room)
  }
}

export function leaveWebSocket(param) {
  for (const i in eList) {
    const item = eList[i]
    if (item === param) {
      eList.splice(i, 1)
    }
  }
  let haveRoom = false
  eList.forEach(item => {
    if (item && item.room === param.room) {
      haveRoom = true
    }
  })
  if (!haveRoom) {
    unBindRoom(param.room)
  }
}

function bindRoom(room) {
  if (!ws || !isConnect) {
    console.error(`bindRoom ${room} worry`)
    return
  }
  ws.send(JSON.stringify({
    cmd: 'bindRoom',
    param: room
  }))
  console.log('ws bindRoom ' + room)
}

function unBindRoom(room) {
  if (!ws || !isConnect) {
    console.error(`unBindRoom ${room} worry`)
    return
  }
  ws.send(JSON.stringify({
    cmd: 'unBindRoom',
    param: room
  }))
  console.log('ws unBindRoom ' + room)
}
